#include "ReceptorFramesAV.h"
#include "Alumno.h"
#include <iostream>
#include <string.h>
#include <fstream>
ReceptorFramesAV::ReceptorFramesAV(Socket *socket,
		ReproductorVideo *reproductorVideo, Altavoz * altavoz, Alumno *alumno) {
	this->socket = socket;
	this->reproductorVideo = reproductorVideo;
	this->altavoz = altavoz;
	this->alumno = alumno;
}

ReceptorFramesAV::ReceptorFramesAV() {
	socket = NULL;
}

void ReceptorFramesAV::run() {
	int recibio = 0;
	int tam_arg;
	static int tam_aux = 0;
	char buffer[TAM_BLOQUE_INI];
	std::string clave, nombre_usuario, codClase, codCurso;
	char cod_op;
	bool clase_iniciada = false;
	while(1) {
		recibio = 0;
		// Recibe el codigo
		if(!socket->recibir(buffer, sizeof(char))) {
			std::cerr << "Codigo no recibido" << std::endl;
			break;
		}
		cod_op = buffer[0];
		if((cod_op != '1') && (cod_op != '0') && (cod_op != 'V') && (cod_op != 'A')) {
			std::cerr << "Codigo de Operacion Invalido" << std::endl;
			break;
		}
		if(!socket->recibir(&buffer[1], sizeof(int))) {
			std::cerr << "Tamaño del bloque no recibido" << std::endl;
			break;
		}
		tam_arg = *(unsigned int*)&buffer[1];
		memmove(buffer, &buffer[(TAM_BLOQUE_INI -1)], TAM_BLOQUE_INI - (TAM_BLOQUE_INI -1));
		char *argumentos = new char[tam_arg];
		if(tam_arg > 0) {
			if(!(socket->recibir(argumentos, tam_arg))) {
				std::cerr << "Bloque de argumentos no recibido" << std::endl;
				break;
			}
		}

		if(!clase_iniciada) {
			alumno->levantarVentana();
			alumno->transmitiendo(true);
			clase_iniciada = true;
		}

		switch(cod_op) {
		case('0'): {  // Codigo de fin de la clase
			alumno->transmitiendo(false);
			clase_iniciada = false;
			break;
		}
		case('1'): {  // Codigo de inicio de la clase
		  alumno->levantarVentana();
		  alumno->transmitiendo(true);
		  // El alumno entra a clase y le avisa al servidor a que curso y clase
		  alumno->entro_a_clase(argumentos, tam_arg);
		}
		case('V'): {  // Codigo de frame de video recibido
			gdk_threads_enter();
			reproductorVideo->mostrar_frame((uint8_t *)argumentos, tam_arg);
			gdk_threads_leave();
			break;
		}
		case('A'): {  // Codigo de frame de audio recibido
			const int tam = 250;
			static uint8_t aux[tam + 1000];
			memcpy(&aux[tam_aux], argumentos, tam_arg);
			tam_aux += tam_arg;
			if(tam_aux >= tam) {
				int auxiliar = altavoz->ejecutar(aux, tam_aux);
				memmove(aux, aux + tam_aux - auxiliar , auxiliar);
				tam_aux = auxiliar;
			}
			break;
		}
		}
		delete[] argumentos;
	}
}

ReceptorFramesAV::~ReceptorFramesAV() {
}
